package com.zzy.furns.web;

import com.zzy.furns.domain.Furn;
import com.zzy.furns.domain.Page;
import com.zzy.furns.service.FurnService;
import com.zzy.furns.service.impl.FurnServiceImpl;
import com.zzy.furns.utils.DataUtils;
import com.zzy.furns.utils.WebUtils;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.util.*;

public class FurnServlet extends BasicServlet{
    private FurnService furnService = new FurnServiceImpl();
    private void list(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        List<Furn> furns = furnService.queryFurns();
        req.setAttribute("furns",furns);
        req.getRequestDispatcher("/views/manage/furn_manage.jsp").forward(req,resp);
    }

    private void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /**
         * 后端数据校验
         * 1.为什么有前端校验还需要后端校验呢？
         *      防止有人绕过前端直接访问后端（postman等）
         * 2.使用正则表达式进行校验
         * 3.使用异常捕获机制对单个输入进行校验，并给出明确提示信息
         * 4.使用异常捕获机制对整个输入进行校验，并给出模糊提示信息
         */
//        String name = req.getParameter("name");
//        String maker = req.getParameter("maker");
//        BigDecimal price = new BigDecimal(req.getParameter("price"));
//        Long sales = Long.parseLong(req.getParameter("sales"));
//        Long stock = Long.parseLong(req.getParameter("stock"));
//        String imgPath = "assets/images/product-image/default.jpg";

//        Furn furn = new Furn(null, name, maker, price, sales, stock, imgPath);

        //使用BeanUtils将前端提交的数据自动封装成JavaBean对象
        /**
         * Map<String, String[]> parameterMap = req.getParameterMap();
         *      注意：Map集合中的值为String[]
         * req.getParameterMap().forEach((key,value) -> System.out.println(key + "：" + Arrays.toString(value)));
         *      action：[add]
         *      name：[餐边柜]
         *      maker：[尚雅家居]
         *      price：[3168]
         *      sales：[100]
         *      stock：[80]
         */

        Furn furn = DataUtils.copyParamToBean(new Furn(), req.getParameterMap());

//        Furn furn = new Furn();
//        try {
//            BeanUtils.populate(furn,req.getParameterMap());
//        } catch (Exception e) {
//            throw new RuntimeException(e);
//        }

        if (furnService.add(furn)){
            //保存家居成功
            /**
             * 此处不能直接请求转发到furn_manage.jsp界面，应该重新读取家具信息在进行展示
             * 1.list(req,resp) 会造成表单重复提交问题
             * 2.采用重定向方式，分成两次请求
             * 3.resp.sendRedirect()发起的是Get请求
             */
            //计算最后一页记录数
            Integer rowTotal = DataUtils.parseInt(req.getParameter("rowTotal"));
            Integer pageSize = DataUtils.parseInt(req.getParameter("pageSize"));
            Integer pageNo = DataUtils.parseInt(req.getParameter("pageNo"));
            Integer lastPageSize = (rowTotal - 1) % pageSize + 1;

            if (lastPageSize == pageSize){
                //如果最后一页数据数等于pageSize，则pageNo + 1
                resp.sendRedirect(req.getContextPath() + req.getServletPath() + "?action=page&pageNo=" + (pageNo + 1) + "&pageSize=" + pageSize);
                return;
            }
            resp.sendRedirect(req.getContextPath() + req.getServletPath() + "?action=page&pageNo=" + req.getParameter("pageNo")
                                                                                + "&pageSize=" + req.getParameter("pageSize"));
            return;
        }

        System.out.println("添加家居失败");
    }

    /**
     * 根据id删除家居
     */
    private void deleteFurnById(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Integer id = DataUtils.parseInt(req.getParameter("id"));
        if (furnService.deleteFurnById(id)){
            //删除成功 返回家居列表 不止直接返回furn_manage.jsp界面，应该是重新执行查询操作
            //依旧不能使用请求转发 以防重复提交
            /**
             * 当一次请求中有表单提交时，需要慎重考虑是否以及什么时候可以用请求转发
             */
            resp.sendRedirect(req.getContextPath() + req.getServletPath() + "?action=page&pageNo=" + req.getParameter("pageNo")
                                                                             + "&pageSize=" + req.getParameter("pageSize"));
            return;
        }

        System.out.println("删除家居失败");
    }

    /**
     * 根据id查询家居
     */
    private void queryFurnById(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Integer id = DataUtils.parseInt(req.getParameter("id"));
        Furn furn = furnService.queryFurnById(id);
        if (furn != null){
            //在一次请求中如果存在与数据库的交互，应该避免用请求转发，以减轻对数据库的压力？
            req.setAttribute("updateFurn",furn);
            req.getRequestDispatcher("/views/manage/furn_update.jsp").forward(req,resp);
            return;
        }

        System.out.println("查询不到id= " + id +" 的家居信息");
    }

//    /**
//     * 修改家居信息
//     */
//    private void updateFurn(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        Integer pageNo = DataUtils.parseInt(req.getParameter("pageNo"));
//        Integer pageSize = DataUtils.parseInt(req.getParameter("pageSize"));
//        Furn furn = DataUtils.copyParamToBean(new Furn(), req.getParameterMap());
//        //这里应该对furn实例数据进行校验，以防有人绕过前端校验直接访问该Servlet方法，导致数据库中数据的损坏
//        if (furnService.updateFurn(furn)){
//            //更新成功 查询家居列表后跳转回furn_manage.jsp界面
//            resp.sendRedirect(req.getContextPath() + req.getServletPath() + "?action=page&pageNo=" + pageNo + "&pageSize=" + pageSize);
//            return;
//        }
//
//        System.out.println("id= " + furn.getId() + " 的家居信息更新错误");
//    }

    /**
     * 修改家居信息（附带图片上传）
     */
    private void updateFurn(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Integer id = DataUtils.parseInt(req.getParameter("id"));

        //根据id查询家居数据
        Furn oldFurn = furnService.queryFurnById(id);

        //创建一个Map集合，用于存储数据
        HashMap<String, Object> map = new HashMap<>();

        //判断提交的表单是否为文件表单
        if (ServletFileUpload.isMultipartContent(req)){
            //创建一个文件表单解析器
            DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
            ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
            try {
                //解析上传的文件表单
                List<FileItem> list = servletFileUpload.parseRequest(req);
                //遍历解析的文件表单集合
                for (FileItem fileItem : list) {
                    //判断是否为文本
                    if (fileItem.isFormField()){
                        //是普通文本
                        String fieldName = fileItem.getFieldName();
                        /**
                         * name
                         * maker
                         * price
                         * sales
                         * stock
                         */
                        String fieldVal = fileItem.getString("utf-8");
                        /**
                         * 简约风格小椅子
                         * 熊猫家居
                         * 180.00
                         * 666
                         * 5
                         */
                        map.put(fieldName,fieldVal);
                    } else {
                        //二进制文件
                        String name = fileItem.getName();
                        String fieldName = fileItem.getFieldName();
                        /**
                         * ===================
                         * 5.jpg
                         * ===================
                         */

                        if ("".equals(name)){
                            //没有更新图片
                            continue;
                        }

                        //指定目录
                        String catalogName = "/upload/";
                        //获取目录的绝对路径
                        String realPath = req.getServletContext().getRealPath(catalogName);
                        //根据绝对路径创建子目录
                        File file = new File(realPath + WebUtils.getYearMonthDayHourMinute());
                        //判断目录是否存在
                        if (!file.exists()){
                            file.mkdirs();
                        }

                        //重新组装上传的文件名
                        String storeName = UUID.randomUUID() + "_" + name;
                        //将二进制文件保存
                        try {
                            fileItem.write(new File(file,storeName));
                            fileItem.getOutputStream().close();
                            String newImgPath = "upload/" + WebUtils.getYearMonthDayHourMinute() + "/" + storeName;
                            map.put(fieldName,newImgPath);
                        } catch (Exception e) {
                            throw new RuntimeException(e);
                        }
                    }
                }
                Furn newFurn = new Furn();
                BeanUtils.populate(newFurn,map);
                if (furnService.updateFurn(newFurn)){
                    if (newFurn.getImgPath() != null){
                        String realPath = req.getServletContext().getRealPath(oldFurn.getImgPath());
                        File file = new File(realPath);
                        file.delete();
                    }
                    //修改成功
                    resp.sendRedirect(req.getContextPath() + req.getServletPath() + "?action=page&pageNo=" + map.get("pageNo") + "&pageSize=" + map.get("pageSize"));
                } else {
                    //更新失败
                    System.out.println("更新失败");
                    System.out.println("原数据=======>" + oldFurn);
                    System.out.println("新数据=======>" + newFurn);
                }
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

//        Integer pageNo = DataUtils.parseInt(req.getParameter("pageNo"));
//        Integer pageSize = DataUtils.parseInt(req.getParameter("pageSize"));
//        Furn furn = DataUtils.copyParamToBean(new Furn(), req.getParameterMap());
//        //这里应该对furn实例数据进行校验，以防有人绕过前端校验直接访问该Servlet方法，导致数据库中数据的损坏
//        if (furnService.updateFurn(furn)){
//            //更新成功 查询家居列表后跳转回furn_manage.jsp界面
//            resp.sendRedirect(req.getContextPath() + req.getServletPath() + "?action=page&pageNo=" + pageNo + "&pageSize=" + pageSize);
//            return;
//        }
//
//        System.out.println("id= " + furn.getId() + " 的家居信息更新错误");
    }

    /**
     * 分页查询
     */
    private void page(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        Integer pageNo = DataUtils.parseInt(req.getParameter("pageNo"));
        Integer pageSize = DataUtils.parseInt(req.getParameter("pageSize"));
        if (pageNo == -1 || pageSize == -1){
            System.out.println("pageNo 或 pageSize 转换错误");
            return;
        }
        Page<Furn> page = furnService.page(pageNo, pageSize);
        req.setAttribute("page",page);
        req.getRequestDispatcher("/views/manage/furn_manage.jsp").forward(req,resp);
    }
}
